<?php defined('SYSPATH') or die('No direct script access.');

class ViregWizard_Controller extends WizardController {

    public $currencyCodeList = array('CZK');
    
    public function __construct() {
        parent::__construct(
                'ViregWizardData', /* data class name */
                '/user/viregWizard', /* wizardPath */
                'user/viregWizardLayout', /* contentLayout */
                ViregWizardData::$STEPS
        );
        if (($this->data == null || $this->data->viSeminar == null) && Router::$method != 'enter') {
            $this->redirect('/user/seminarChoice');
        }
        $this->activeMenuItem = UserMenu::$SEMINAR_CHOICE;
    }

    /* ------------------------------------------------------------------- */
    /* - Seminar                                                         - */
    /* ------------------------------------------------------------------- */

    public function enter() {
        $this->newData();
        
        // GET request from /user/seminarChoice
        $viSeminarId = $this->input->get('id');

        if (! valid::isId($viSeminarId)) {
            $this->msg->error('error.invalidId');
            $this->redirect('/user/seminarChoice');
            return;
        }

        $viSeminar = $this->dao->getById('vi_seminar', $viSeminarId);
        if (! $viSeminar) {
            $this->redirect('/user/seminarChoice');
            return;
        }
        
        $priceList = $this->dao->getByField('vi_seminar_price', 'vi_seminar_id', $viSeminarId);
        foreach ($priceList as $price) {
            $viSeminar['prices-' . $price['currency_code']] = $price;
        }

        // Bank account
        $viSeminar['bankAccount'] = $this->dao->getById('bank_account', $viSeminar['bank_account_id']);
        $viSeminar['dayCount'] = seminarHelper::dayCount($viSeminar);
        $this->data->viSeminar = $viSeminar;
        
        $earlyDiscountHeight = $viSeminar['prices-' . ViregWizardData::$CURRENCY_CODE]['early_discount'];
        if ($earlyDiscountHeight) {
        	$dateDiff = date::diffDates(date('Y-m-d'), $viSeminar['early_discount_deadline']);
        	if ($dateDiff >= 0) {
        		$this->data->earlyDiscountHeight = $earlyDiscountHeight;
        	}
        }
        
        $this->redirect('/user/viregWizard/step');
    }

    /* ------------------------------------------------------------------- */
    /* - Options                                                         - */
    /* ------------------------------------------------------------------- */

    protected function optionsStep() {
        $optionsForm = array();
        if ($this->data->optionsForm) {
            $optionsForm = $this->data->optionsForm;
        }
        else {
            // Default values
            $optionsForm['last_meal_in_package'] = sql::$FALSE;
            $optionsForm['is_instructor'] = sql::$FALSE;
            $optionsForm['night_count'] = $this->data->viSeminar['night_count'];

            if ($this->getAuthOrSubstituteUser('is_ztp')) {
                $optionsForm['social_discount_applied'] = sql::$TRUE;
            }

            // Pre-select all meals
            $optionsForm['mealSelection'] = array();
            for ($dayIndex = 0; $dayIndex < $this->data->viSeminar['dayCount']; $dayIndex++) {
            	$date = format::isoDate(date::addDays($this->data->viSeminar['begin_date'], $dayIndex));
                foreach (registrationHelper::$MEAL_LIST as $meal) {
                    if ($dayIndex == 0) {
                        if ($this->data->viSeminar['first_meal'] == 'lunch' && $meal == 'breakfast') {
                            continue;
                        }
                        if ($this->data->viSeminar['first_meal'] == 'dinner' && $meal != 'dinner') {
                            continue;
                        }
                    }
                    if ($dayIndex + 1 == $this->data->viSeminar['dayCount']) {
                        if ($this->data->viSeminar['last_meal'] == 'breakfast' && $meal != 'breakfast') {
                            break;
                        }
                        if ($this->data->viSeminar['last_meal'] == 'lunch' && $meal == 'dinner') {
                            break;
                        }
                    }
                    $valueAndId = $date . '_' . $meal;
                    $optionsForm['mealSelection'][] = $valueAndId;
                }
            }
        }
        
       	$optionsForm['early_discount'] = $this->data->earlyDiscountHeight;
        
        $this->optionsData();
        $this->optionsCalculateData($optionsForm);
    }

    protected function optionsData() {
        $currencyOptions = array(
            'CZK' => text::get('currency.CZK')
        );
        $this->viewData['currencyOptions'] = $currencyOptions;

        // Accomodation types
        $this->viewData['viAccomodationTypeList'] = $this->dao->
                fetchViAccomodationTypeListForSeminar($this->data->viSeminar['id']);
    }

    protected function optionsCalculateData($optionsForm) {
        $viSeminarPriceList = $this->data->viSeminar['prices-' . ViregWizardData::$CURRENCY_CODE];
        
        if ($optionsForm['vi_accomodation_type_code']) {
            $optionsForm['viAccomodationType'] = $this->dao->fetchViAccomodationTypeForSeminar(
                    $this->data->viSeminar['id'], $optionsForm['vi_accomodation_type_code']);

            // Calculate the total price only if the accomodation type is chosen.
            $viRegistration = array (
            		'bank_payment_discount' => $this->data->bankPaymentDiscountHeight,
            		'early_discount' => $this->data->earlyDiscountHeight
            );
            $optionsForm = registrationHelper::calculateTotalPrice($viRegistration, $optionsForm, $viSeminarPriceList);
        }
        else {
            $optionsForm['meals_price'] = registrationHelper::calculateMealsPrice(
                    $optionsForm['mealSelection'], $viSeminarPriceList);
        }

        // If the course fee is not set yet or the user is not admin,
        // set the course fee to its default value from the seminar.
        if ($optionsForm['course_fee'] === NULL || ! $this->getAuthUser('is_admin')) {
            $optionsForm['course_fee'] = $viSeminarPriceList['course_fee'];
        }

        $this->viewData['optionsForm'] = $optionsForm;

        // mealForm.php is used also for displaying the registration in myRegistrationDisplay,
        // so we cannot use $this->data->viSeminar there directly.
        $this->viewData['viSeminar'] = $this->data->viSeminar;
        return $optionsForm;
    }

    protected function optionsNext() {
        $optionsForm = $this->postToDbValues();
        $optionsForm = $this->optionsCalculateData($optionsForm);

        // Validation
        if (valid::isEmpty($optionsForm['vi_accomodation_type_code'])) {
            $this->msg->error('viregWizard.error-chooseAccomodationType');
        }
        if ($this->msg->hasErrors()) {
            return FALSE;
        }

        if (! $optionsForm['social_discount_applied']) {
            $optionsForm['social_discount_applied'] = sql::$FALSE;
        }

        if (! $optionsForm['is_instructor']) {
            $optionsForm['is_instructor'] = sql::$FALSE;
        }

        $this->data->optionsForm = $optionsForm;
    }

    public function saveForm() {
        $optionsForm = $this->postToDbValues();
        $this->data->optionsForm = registrationHelper::processSavedForm(
                $optionsForm, $this->data->optionsForm, $this->data->viSeminar);
        $this->redirect($this->stepUrl);
    }

    /* ------------------------------------------------------------------- */
    /* - Payment type                                                    - */
    /* ------------------------------------------------------------------- */

    protected function paymentTypeStep() {
        $this->paymentTypeData();
        $paymentTypeForm = array();
        if ($this->data->paymentTypeForm) {
            $paymentTypeForm = $this->data->paymentTypeForm;
        }
        else {
            // Default values
            if ($this->data->optionsForm['is_instructor']) {
                $paymentTypeForm['payment_type'] = 'honorarium';
            }
        }
        $this->viewData['paymentTypeForm'] = $paymentTypeForm;
    }

    protected function paymentTypeData() {
        // Payment type options - instructors do not pay, they have it as a honorarium.
        $this->viewData['paymentTypeOptions'] = registrationHelper::getPaymentOptions(
        		$this->data->viSeminar,
                $this->data->optionsForm['is_instructor'],
                $this->data->viSeminar['prices-' . ViregWizardData::$CURRENCY_CODE]['bank_payment_discount'],
                ViregWizardData::$CURRENCY_CODE);
        
    }

    protected function paymentTypeNext() {
        $paymentTypeForm = $this->postToDbValues();
        $this->viewData['paymentTypeForm'] = $paymentTypeForm;

        // Validation
        if (valid::isEmpty($paymentTypeForm['payment_type'])) {
            $this->msg->error('viregWizard.error-choosePaymentType');
        }
        if ($this->msg->hasErrors()) {
            return FALSE;
        }
        
        if ($paymentTypeForm['payment_type'] == 'bank') {
            $this->data->bankPaymentDiscountHeight = $this->data->viSeminar['prices-' . ViregWizardData::$CURRENCY_CODE]['bank_payment_discount'];
        }
        else {
            $this->data->bankPaymentDiscountHeight = 0;
        }
        
        // Calculate the total price
        $this->data->optionsForm = $this->optionsCalculateData($this->data->optionsForm);

        $this->data->paymentTypeForm = $paymentTypeForm;
    }

    /* ------------------------------------------------------------------- */
    /* - Summary                                                         - */
    /* ------------------------------------------------------------------- */

    protected function summaryStep() {
        $this->viewData['viSeminar'] = $this->data->viSeminar;
        $this->viewData['optionsForm'] = $this->data->optionsForm;
        $this->viewData['paymentTypeForm'] = $this->data->paymentTypeForm;
        $this->viewData['bankPaymentDiscount'] = $this->data->bankPaymentDiscountHeight;
        $this->summaryData();
    }

    protected function summaryData() {
        $this->optionsData();
    }

    /* ------------------------------------------------------------------- */
    /* - Finish                                                          - */
    /* ------------------------------------------------------------------- */

    public function finish() {
        $this->dao->getDb()->beginTransaction();
        $viRegistration = null;
        try {
            // Save the registration
            $viRegistration = array(
                'created_at'    => date('Y-m-d', $now),
                'vi_seminar_id' => $this->data->viSeminar['id'],
                'notes'         => $this->data->paymentTypeForm['notes'],
                'person_id'     => $this->getAuthOrSubstituteUser('id'),
                'total_price'   => $this->data->optionsForm['total_price'],
                'bank_payment_discount' => $this->data->bankPaymentDiscountHeight,
            	'early_discount' => $this->data->earlyDiscountHeight,
                'social_discount_applied' => $this->data->optionsForm['social_discount_applied'],
                'currency_code' => ViregWizardData::$CURRENCY_CODE,
                'payment_type'  => $this->data->paymentTypeForm['payment_type'],
                'vi_accomodation_type_code' => $this->data->optionsForm['vi_accomodation_type_code'],
                'last_meal_in_package' => $this->data->optionsForm['last_meal_in_package'],
                'night_count'   => $this->data->optionsForm['night_count'],
                'course_fee'    => $this->data->optionsForm['course_fee'],
                'meals_price'   => $this->data->optionsForm['meals_price'],
                'accomodation_price' => $this->data->optionsForm['accomodation_price'],
                'is_instructor' => $this->data->optionsForm['is_instructor'],
                'extra_discount' => $this->data->optionsForm['extra_discount'],
                'created_at'    => time()
            );
            $viRegistration['id'] = $this->dao->insert('vi_registration', $viRegistration);

            $this->data->viRegistration = $viRegistration;

            // Save the meals
            if (is_array($this->data->optionsForm['mealSelection'])) {
                $this->dao->saveMealSelection($this->data->optionsForm['mealSelection'], $viRegistration['id']);
            }

            // Commit the transaction
            $this->dao->getDb()->commit();
        }
        catch (Exception $e) {
            // If something raised an exception in our transaction block of statements,
            // roll back any work performed in the transaction
            $this->dao->getDb()->rollBack();

            // Recoverable: vi_registration_account_seminar_unq constraint violated ...
            if (strpos($e->getMessage(), 'vi_registration_person_seminar_unq')) {
                $this->msg->error('viregWizard.error-alreadyRegistered', $this->data->viSeminar['name']);
                $this->redirect($this->stepUrl);
            }
            
            // Clear the wizard data
            $this->clearData();
            
            throw $e;
        }

        // Send a confirmation email to the user.
        $userEmailLang = $this->getAuthOrSubstituteUser('preferred_language');
        $dateInterval = null;
        if ($this->data->viSeminar['begin_date'] == $this->data->viSeminar['end_date']) {
            $dateInterval = '(' . format::date($this->data->viSeminar['begin_date']) . ')';
        }
        else {
            $dateInterval = '(' . format::dateInterval($this->data->viSeminar['begin_date'], $this->data->viSeminar['end_date']) . ')';
        }
        $emailBodyParams = array(
            $this->data->viSeminar['name'] . ' ' . $dateInterval,
            format::decimal($viRegistration['total_price']) . ' ' . text::getInLang($userEmailLang, 'currency.mark-' . $viRegistration['currency_code']),
            text::getInLang($userEmailLang, 'viregWizard.paymentType-' . $viRegistration['payment_type'])
        );
        if ($viRegistration['payment_type'] == 'bank') {
            $emailBodyParams[] = text::getInLang($userEmailLang, 'bankAccount.number') . ': ' . $this->data->viSeminar['bankAccount']['number'] . '/' . $this->data->viSeminar['bankAccount']['bank_number'] . "\n" .
                    text::getInLang($userEmailLang, 'viSeminar.variable_symbol') . ': ' . $this->data->viSeminar['variable_symbol'] . "\n" .
                    text::getInLang($userEmailLang, 'myRegistration.specific_symbol') . ': ' . $viRegistration['id'] . "\n";
        }
        else {
            $emailBodyParams[] = "";
        }
        $mailBody = text::getInLang($userEmailLang, 'viregWizard.confirmationEmail-body', $emailBodyParams);
        $mailPerson = $this->getAuthOrSubstituteUser();
        $mailResult = email::sendInUtf8(
                $mailPerson['first_name'] . ' ' . $mailPerson['last_name'],
                $mailPerson['email'],
                text::getInLang($userEmailLang, 'viregWizard.confirmationEmail-title'),
                email::addHeadingAndClosing($mailBody, $mailPerson, $userEmailLang));
        if (! $mailResult) {
            $this->msg->warning('viregWizard.mailFailedRegistrationValid');
        }

        // Send info email to admin that there is a new registration
        if (! $this->getAuthUser('is_admin')) {
            $mailResult = email::sendInUtf8(Kohana::config('yosemin.registrationManager-name'),
                    Kohana::config('yosemin.registrationManager-mail'),
                    'Nová přihláška na: ' . $this->data->viSeminar['name'],
                    'Jméno: ' . format::personFullName($this->getAuthOrSubstituteUser()) . "\n" .
                    'Seminář: ' . $this->data->viSeminar['name']);
            if (! $mailResult) {
            }
        }
        $this->redirect('/user/viregWizard/success?id=' . $viRegistration['id']);
    }

    public function success() {
        $registrationId = $this->input->get('id');
        $this->contentLayout = 'user/userLayout';
        $this->renderSubview('user/viregWizard/wizardSuccess');
        $this->clearData();
    }
}